////////////////////////////////////////////////////////////////////////////////
//
//	Original file Name: LevelManager.java
//	Originating Author: Jon Whitefield
//	
//	Description: Holds all the level objects together meaning that 
//				 you don't create levels you request them 
//
////////////////////////////////////////////////////////////////////////////////

package com.jjw.game.world.level;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * Holds all the level objects together meaning that you don't create levels you request them  
 */
public class LevelManager {
	
	//--------------------------------------------------------------------------
	//
	//Properties
	//
	//--------------------------------------------------------------------------
	
	//----------------------------------
	// Public
	//----------------------------------
	
	//----------------------------------
	//  Getters / Setters
	//----------------------------------
	
	//----------------------------------
	// Private
	//----------------------------------
	
	/**
	 * Location the levels are stored
	 */
	private static final String LEVEL_DIRECTORY = "level"; 

	/**
	 * Level file extension
	 */
	private static final String LEVEL_FILE_EXTENTION = "lvl"; 
	
	/** 
	 * Instance for the level managers singleton
	 */
	private static LevelManager instance;
	
	/**
	 * List of all the levels
	 */
	private Map<String, Level> levels = null;
	
	//--------------------------------------------------------------------------
	//
	//  Methods
	//
	//--------------------------------------------------------------------------
		
	//----------------------------------
	// Public
	//----------------------------------
	
	LevelManager() {
		
		//Create a new map to store the levels
		this.levels = new HashMap<String, Level>();
		
		//Find all the levels in this directory
		this.findLevels( new File(LEVEL_DIRECTORY) );
	}
	
	/**
	 * Gets an instance of the level manager
	 */
	public static LevelManager getInstance() {
		
		//If we don't have a level manager then create one
		if( instance == null ) {
			instance = new LevelManager();
		}
		
		//Returns the instance of the level manager
		return instance;
	}
	
	/**
	 * Gets a level by the reference passed in
	 * 
	 * @param levelReference	the reference for the level you want
	 * 
	 * @return					the level that relates to that reference or null of null if not found 
	 */
	public Level getLevelByReference( String levelReference ) {
		
		//If we don't have a levels list return null
		if( this.levels == null )
			return null;
		
		//Get the level for this reference
		Level levelForReference = this.levels.get( this.formatLevelStringReference(levelReference) );
		
		//If the level isn't null make sure its loaded 
		if( levelForReference != null )	{
			
			//If the level isn't already loaded then load it
			if( !levelForReference.getIsLoaded() )
				levelForReference.loadLevel();
		}
		
		//Return the found level 
		return levelForReference;
	}
	
	//----------------------------------
	// Private
	//----------------------------------
	
	/**
	 * Looks for all the levels file in the levels folder
	 */
	private void findLevels( File directory ) {
		
		//Loop through all the files in the directory 
		for( File file : directory.listFiles() ) {
			
			//Check if its a file or a folder
			if( file.isFile() ) {
				
				//Check that its a level file
				if( file.getName().contains("."+LEVEL_FILE_EXTENTION) ) {

					//Get the level reference
					String levelReference = this.formatLevelFileReference(file); 
					
					//Put the level onto the map with its reference
					this.levels.put( levelReference, new Level(levelReference,file));
				}

			}else{
				
				//Search the file deeper for more level files
				this.findLevels(file);
			}
		}		
	}
	
	/**
	 * Creates a level reference from a file 
	 *  
	 * @param 	file the level file we are creating the reference for
	 * 	
	 * @return	the level file reference	
	 */
	private String formatLevelFileReference( File file ) {
		
		//Format the file name to remove the extention and send it to be formatted
		return this.formatLevelStringReference( file.getName().replace("."+LEVEL_FILE_EXTENTION, "") );		
	}
	
	/**
	 * Formats the level file reference passed in so they are uniform 
	 * 
	 * @param levelReference
	 * @return
	 */
	private String formatLevelStringReference( String levelReference ) {
		
		//Lower case the reference and trim it
		return levelReference.toLowerCase().trim();
	}
	
	//----------------------------------
	// Overridden / Implemented
	//----------------------------------
}
